package com.hong.utils.executors;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * @Auther: Administrator
 * @Date: 2018/7/28 20:48
 * @Description:
 */
public class CompletionServiceExample1
{
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        futureDefect2();

    }

    /**
     * 缺点一:
     * 一但get就阻塞住了。
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void futureDefect1() throws ExecutionException, InterruptedException {
        ExecutorService service  = Executors.newFixedThreadPool(2);
        Future<Integer> future = service.submit(()->{
            try {
                TimeUnit.SECONDS.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 100;
        });
        System.out.println("=====================");
        future.get();
    }

    /**
     * no callback
     * 缺点二:
     * 无法实时返回值，不清楚是10先运行还是20先运行，哪个结果先得到。
     */
    public static void futureDefect2() throws InterruptedException, ExecutionException {
        ExecutorService service = Executors.newFixedThreadPool(2);
       final List<Callable<Integer>> callableList = Arrays.asList(
                () -> {
                    sleep(10);
                    System.out.println("The 10 finished.");
                    return 10;
                }, () -> {
                    sleep(20);
                    System.out.println("The 20 finished.");
                    return 20;
                }
        );
        /*List<Future<Integer>> futureList = service.invokeAll(callableList);
        Integer v1 = futureList.get(1).get();
        System.out.println(v1);
        Integer v2 = futureList.get(0).get();
        System.out.println(v2);*/
        /**
         * 解决方案
         */
        List<Future<Integer>> futures  = new ArrayList<>();
        futures.add(service.submit(callableList.get(0)));
        futures.add(service.submit(callableList.get(1)));

        for(Future<Integer> future:futures){
            System.out.println(future.get());
        }

    }

    /**
     * 休眠
     * @param seconds
     */
    public static void sleep(long seconds){
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
